"""
@-*- coding: utf-8 -*-
@ python：python 3.8
@ 创建人员：ylx
@ 创建时间：2025/4/27 下午1:46
@ 内容：主要学习了以下内容
1.文件的读写，生成器读取大文件
2.os.path 模块的使用
3.time datetime模块学习
"""
import os.path

# import sys
#
# a = [1, 2, 3]  #创建列表对象，引用计数为1
# b = a  #再创建一个引用，计数为2
#
# print(sys.getrefcount(a))
# del b
# print(sys.getrefcount(a))
# del a


# import copy
#
# # 原始列表
# original_list = [1, 2, [3, 4]]
#
# # 浅拷贝
# shallow_copied_list = copy.copy(original_list)
#
# # 修改原始列表的嵌套部分
# original_list[2][0] = "modified"
# original_list[0] = "hhhh"
#
# print(original_list)        # 输出: [1, 2, ['modified', 4]]
# print(shallow_copied_list)  # 输出: [1, 2, ['modified', 4]]

# # 一般的写法，使用open打开后，写完务必要close
# # w 是覆盖写 a是追加写
# file = open("example.txt", "a")
# file.write("\ntest1")
# file.write("\ntest2")
# file.close()

# # 写入单行内容
# with open("example.txt", "w", encoding="utf-8") as file:
#     file.write("hello\n")
#     file.write("liming\n")
#     file.write("在吗？\n")
#     file .write("在的")

# # 覆盖写，写入多行,然后再追加写入单行
# lines = ["nihao\n", "wo hen hao \n"]
# with open("example.txt", "w") as file:
#     file.writelines(lines)

# with open("example.txt", "a") as file:
#     file.write("wo zhen de hen hao")


# # 使用 追加模式新建文件，若文件已有，文件内容不会被覆盖
# file = open("test.txt", "a")
# file.close()


# # 使用 覆盖写模式新建文件，若文件已有，文件内容被覆盖
# file = open("tests.txt", "w")
# file.close()


# read 读取文件的全部内容，返回一个字符串，可以指定的读取多少个字节
# 返回的完整字符串包含换换行符号
# readline 一次读一行，每次调用，读取一行内容包含\n，多次调用可以逐行读取
# 读取到文件末尾返回空字符串""
# readlines 读取所有行，返回列表，一次性读取所有行，返回一个列表
# 每个元素是一行，包含\n
# 最佳实践
# 虽然 readline() 可以逐行读，但最推荐的方式是直接遍历文件对象：
# with open('example.txt', 'r', encoding='utf-8') as f:
#     for line in f:  # 自动按行读取，内存友好！
#         print(line.strip())


# 读取整个文件的内容
# example.txt 文本内容
# nihao
# wo hen hao
# wo zhen de hen hao

# with open("example.txt", "r", encoding="utf-8") as file:
#     content = file.read()
#     print(content)
#
# print("------")
# print(content, type(content))
# print(repr(content))    # 读取文件原始内容'nihao\nwo hen hao \nwo zhen de hen hao'


# 读取文件一行的内容
# with open("example.txt", "r") as file:
#     content = file.readline()
#     print(content)
#     content = file.readline()
#     print(content)
#     content = file.readline()
#     print(content)
#     content = file.readline()
#     print(1111)
#     print(content)
#     print

#使用 readline() 方法读取全部文件
# with open("example.txt", "r") as file:
#     while True:
#         content = file.readline()
#         if not content:
#             break
#         print(content)
#
# with open("example.txt", "r") as file:
#     while True:
#         content = file.readline()
#         if not content:
#             break
#         print(content.strip())


# # 使用readlines() 读取文件全部
# with open("example.txt", "r") as file:
#     content = file.readlines()
#     print(content)


# with open("example.txt", "r", encoding="utf-8") as file:
#     for f in file:
#         print(f, end="")


# 写一个生成器来读取大文件-A
# def read_big(path):
#     with open(path,"r") as file:
#         while True:
#             content = file.readline().strip()
#             if not content:
#                 break
#             yield content


# 写一个生成器来读取大文件-B
# def read_big(path):
#     with open(path, "r", encoding="utf-8") as file:
#         for f in file:
#             yield f.strip()
#
#
# for a in read_big("example.txt"):
#     print(a)


# # 使用read() 方法 分块读取
# a = []
# with open("example.txt", "r") as file:
#     while True:
#         content = file.read(1) # 每次仅读取1个字符
#         if not content:
#             break
#         a.append(content)
#
# print(a)



# import os
# import shutil


# # os.path.exists()是用于检查文件或目录是否存在的常用方法，存在则返回True，不存在则返回False
# # 一般使用在如读文件前先检查文件是否存在，创建目录前检查是否已存在
# # os.path.isfile(path) 只有是文件才返回True
# # os.path.isdir(path) 只有是目录时才返回True
# # path 支持相对路径，绝对路径 "/Users/yourname/Desktop"（macOS/Linux）或 "C:\\Users\\YourName\\Desktop"（Windows）
# print(os.path.exists("example.txt"))
# if os.path.exists('example.txt'):
#     print(1)
# else:
#     print(2)


# # os.path.abspath(path) 将相对路径转换为绝对路径，既请告诉我这个文件或者目录的完整地址，从根目录开始
# # 返回一个字符串，表示对应的绝对路径，如果给的是绝对路径则原样返回，是相对路径，则转换
# # os.path.abspath(".") 返回当前目录的绝对路径
# # os.getcwd() 返回当前工作目录，绝对路径
# # abspath() 仅做路径拼接并不检查文件是否存在，只是告诉你路径是什么，不会真正的创建东西
# # 结合__file__ 获取当前脚本所在的目录
# # script_dir = os.path.dirname(os.path.abspath(__file__))
# absolute_path = os.path.abspath("example.txt")
# print(absolute_path)


# # os.path.basename() 是Python中用于提取路径中的文件名或者目录名的函数
# # 既请从完整的路径中，把最后那个文件夹或者文件的名字给我
# # 返回一个字符串，返回路径的最后一部分，不在乎是文件或目录
# # 相对路径和绝对路径都是可以的
# # 不检查路径是否存在，仅仅是字符串的处理，不关心文件是否存在
# # 结尾有/ \ 时 因为最后一部分是空的，所以会返回空字符串
# # path = "/Users/name/documents/"
# # name = os.path.basename(path)
# # print(repr(name))  # 输出: ''（空字符串！）
# # 修复方法，使用os.path.normpath() 标准化路径后，再使用os.path.basename()即可
# name = os.path.basename(r".\path\to\example.txt")
# print(name)


# # os.path.dirname()是Python中用于提取路径中的目录部分的常用函数
# # 从完整的路径中，把文件或文件夹所在的上级目录的路径返回
# # 返回path的目录部分，去掉最后一级
# # 返回一个字符串
# # 如果路径仅有比如说1.txt 则返回空字符串
# # 相对路径  绝对路径均适用
# # 只有文件名时
# # os.path.dirname("report.txt")     # 返回: ''
# # os.path.dirname("./report.txt")   # 返回: .
# # os.path.dirname("/report.txt")    # 返回: /
# # os.path.dirname("/")      # 返回: ""
# # os.path.dirname("/home")  # 返回: "/"
# # 获取当前脚本所在的目录
# # script_dir = os.path.dirname(os.path.abspath(__file__))
# dir_name = os.path.dirname(r".\path\to\example.txt")
# print(dir_name)


# # os.path.join() 是Python中的路径拼接方法，可以把各个部分安全的拼接在一起，自动处理斜杠问题
# # 能自动适应不同操作系统的路径分隔符号 Windows使用\  macOS或Linux使用/
# # 返回一个字符串，表示拼接后的完整路径，自动使用当前系统的路径分隔符
# # 注意如果某部分是绝对路径，则会重置前面的部分，绝对路径前的部分会被忽略
# # 会自动处理多余的斜杠
# # 空字符串会被忽略
# # 拼接时正确的顺序是路径在前，文件名在后，如果你反着来， 不会报错，但是拼出来的路径实际上你是无法使用的
# # 路径的语义是错误的
# # os.path.join() 不关心你是文件还是目录，它只是机械的拼接，你自己提供的数据，你必须自己保证
# # 路径顺序符合从外到内，从目录到文件的逻辑
# new_path = os.path.join(r"\a\b", r"test.txt")
# print(new_path)

# os.path.split(path)
# 用于分割文件路径的常用函数，目的是将一个完整的文件路径拆分成目录部分和文件名部分
# os.path.split() 等价于同时调用
# directory = os.path.dirname()
# filename = os.path.basename()
# # 只有文件名，无路径
# path = "example.txt"
# directory, filename = os.path.split(path)
# print("目录:", directory)    # 输出: ''（空字符串）
# print("文件名:", filename)   # 输出: example.txt
# # 路径末尾有斜杠
# path = "/home/user/documents/"
# directory, filename = os.path.split(path)
# print("目录:", directory)    # 输出: /home/user/documents
# print("文件名:", filename)   # 输出: ''（空字符串）
# # 基本用法
# path = "/home/user/documents/example.txt"
# directory, filename = os.path.split(path)
# print("目录:", directory)    # 输出: /home/user/documents
# print("文件名:", filename)   # 输出: example.txt


# # os.getcwd()是Python中一个非常基础且重要的函数，用来获取当前工作目录
# # 既说明你当前文件所在的目录
# # 返回值是一个字符串，表示程序当前所在的绝对路径
# # os.getcwd() 是运行目录，不是.py文件的位置
# # 返回你现在在哪个目录，既我现在运行程序时，是在系统的哪个位置
# print(os.getcwd())


# # os.mkdir() 是Python中用于创建单个目录的函数
# # 创建一个新目录，也就是文件夹，只能创建单个目录，或者换句话说就是新建一个文件夹
# # 要求目录不能已存在，且父目录必须存在
# # 路径path可以是相对路径，或者绝对路径
# # 目录已经存在时，创建会报错，解决方案是，创建时先使用os.path.exists()是否存在
# # 父目录不存在，会报错
# # 可以使用os.makedirs() 创建多级目录
# os.mkdir("20250428")


# # os.makedirs() 创建一个目录，并自动创建所有不存在的父目录
# # 支持相对路径或者绝对路径，支持参数exist_ok 默认为False 如果目录已存在，抛出错误
# # True,如果目录已存在，不报错，静默跳过
# # 实际项目场景中，我们在项目初始化时创建目录结构
# # 我们也会在按日期创建日志目录时使用
# # 总结os.makedirs(path, exists_ok=True) 就是请帮我把path这条路修通，缺哪层就新建哪层，如果已经修好了，也别报错
# os.makedirs("2024-0428/2025-0428")
# os.mkdir("2024-0428/2025-0428-1")


# # os.rmdir()是Python中用于删除空目录的函数
# # 删除一个空文件夹，目录必须存在，且里面没有任何文件或者子目录
# # 支持相对路径或绝对路径
# # 目录不存在，会报错
# # 目录不为空，会报错
# # shutil.rmtree() 删除非空目录，删除指定路径的整个目录树
# # 包括目录中所有的文件，子目录，子文件全部删除
# # 注意，目录不存在会报错，可以配合ignore_errors=True 忽略错误，即使目录不存在或者删除失败也不会报错
# # os.path.isdir()是Python中用于判断一个路径是否为文件夹的函数
# # 如果是一个存在的目录 返回True 如果路径不存在或者是文件等其它类型 返回False
# # os.chdir()是Python中用于改变当前工作目录的函数
# # 将程序的当前工作目录切换到指定的path，之后所有相对路径的操作都会以这个新目录为起点
# # 目录不存在会报错
# # 权限不足，会报错，尤其是系统目录
# # 如果切换路径后做了事，还想回到之前的路径，那么可以在切换之前先使用os.getcwd()将之前的路径保存下来
# # 一般可以结合os.getcwd() 获取当前的工作目录，os.chdir()是设置当前的工作目录
# # os.listdir() 是Python中用于列出目录中所有文件和子目录名称的基础函数
# # 返回指定目录下所有文件和子目录的名称的字符串列表
# # 只返回名字，不包含路径，不包括特殊目录，当前目录.和上级目录..
# # os.listdir() 等价于 os.listdir(".") 列出当前工作目录下的所有内容
# # 目录不存在会报错，传入的是文件而不是目录会报错
# # 返回的是名字列表，不是完整路径
# os.rmdir("20250428")
# shutil.rmtree("2024-0428")
# os.chdir("d:/")
# print(os.getcwd())
# print(os.listdir("."))
# print(os.listdir("./2024-0428"))
# print(os.listdir("d:/"))
# print(os.path.exists("./2024-0428/2025-0428-1"))
# print(os.path.join("aa", "bb", "d:\example",  "d:\example11", "1.txt"))


# next()函数是驱动生成器工作的
# 如果for循环语句没有从生成器中取值，既for循环会自动的对生成器对象使用next()
# 那么只能通过 next来触发生成器
# for num in fib: 类似这种就可以通过for循环自动的调用next，缺点就是不能只获取10个
# 而是会一直获取，所以需要额外的增加限制条件来终止for循环

# 示例：生成无限递增整数
# class InfiniteCounter:
#     def __init__(self):
#         self.count = 0
#
#     def __iter__(self):
#         return self
#
#     def __next__(self):
#         self.count += 1
#         return self.count
#
#
# counter = InfiniteCounter()
# for _ in range(5):  # 只取前 5 个值
#     print(next(counter))
#
# for index, num in enumerate(counter):
#     if index < 5:
#         print(num)
#     else:
#         break


# def fibonacci():
#     a, b = 0, 1
#     while True:
#         yield a
#         a, b = b, a + b
#
#
# fib = fibonacci()
# for _ in range(10):  # 只取前 10 个斐波那契数
#     print(next(fib))
#     # print(fib)


# from collections.abc import Iterator
#
# a = [1,2,3,4]
# b = iter(a)
# print(isinstance(a, Iterator))
# print(isinstance(b, Iterator))
# print(next(b))
# print(next(b))
# print(next(b))
# print(next(b))
# print(111)
# for m in b:
#     print(m, type(m))
#
# print(222)
#
# for aaa in []:
#     print(aaa)
# print(333)


# 大文件读取，不使用生成器，会将大文件全部读进内存，导致异常，下方是使用生成器读取的方案
# def read_big(path):
#     with open(path, "r") as file:
#         for line in file:
#             yield line.strip()
#
#
# # 创建一个生成器对象
# gen = read_big("example.txt")
# for m in gen:
#     print(m)


# 使用for循环对生成器对象，触发生成器运行
# def fibonacci():
#     aa, bb = 0, 1
#     while True:
#         yield aa
#         aa, bb = bb, aa + bb
#
#
# for mm in fibonacci():
#     print(mm)
#     if mm >50:
#         break


# 随机函数
# import random
#
#
# a = [1, 23, 4, 5]
# for mmm in range(5):
#     aa = random.choice(a)
#     print(aa)


# json.loads()  json.load() 和 json.dumps() 是Python中处理json数据的2大核心函数
# json.load() 从文件读取json 变成Python数据
# json.loads() 从字符串读取json，变成Python数据
# json.dump() 把Python数据写入json文件
# json.dumps() 把Python数据转成json字符串    支持参数 ensure_ascii=False 支持中文，否则中文乱码  indent=2 美化格式，缩进2个空格，便于阅读 sort_keys=True 按键名排序
# import json
#
# with open(r"D:\@20250513testa\ylx0519\armory.json", 'r', encoding='utf-8') as f:
#     data = f.read()
#     print(data)  # 打印原始数据
#
# res = json.loads(data)
# print(res, type(res))
#
# res_1 = json.dumps(res)
# print(res_1, type(res_1))


# python中处理时间的2个核心模块
# time 基于时间戳的底层时间操作
# datetime 面向对象的高级日期时间处理
# import time
#
#
# timestamp = time.time()
# print(timestamp)    # 这是unix时间戳
#
# time.sleep(2)   # 延迟 2 秒执行
#
# now_struct = time.localtime()   # 转换为结构化时间
# print(now_struct)
# formatted = time.strftime("%Y-%m-%d %H:%M:%S", now_struct)
# print(formatted)
# # 转回时间戳
# date_str = "2025-08-27 14:30:45"
# struct_time = time.strptime(date_str, "%Y-%m-%d %H:%M:%S")
# timestamp = time.mktime(struct_time)
# print(timestamp)


# # datetime 提供了几个核心类
# # datetime.datetime 日期+时间
# # datetime.date 仅日期
# # datetime.time 仅时间
# # datetime.timedelta 时间差
# from datetime import datetime, time, date, timedelta
#
# # 获取当前时间
# now = datetime.now()
# print(now)
# # 格式化输出
# aa = datetime.now().strftime("%Y%m%d%H%M%S")
# print(aa, type(aa))
#
# formatted = now.strftime("%Y年%m月%d日 %H时%M分%S秒")
# print(formatted, type(formatted))
#
# # 获取当前时间戳
# timestamp = datetime.now().timestamp()
# print(timestamp)
#
# date_str = "2025/08/27 14:30"
# dt = datetime.strptime(date_str, "%Y/%m/%d %H:%M")
# print(dt)  # 2025-08-27 14:30:00
#
# today = date.today()
# print(today)
#
# current_time = time(14, 53, 45)
# print(current_time)
#
# now = datetime.now()
# print(now)
# one_day_later = now + timedelta(days=1)
# print(one_day_later)
